﻿using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System;

namespace Library.HttpHelp
{
    public class HttpHelp
    {
        #region 借鉴市平台事件推送 一表统管 请求公共方法
        /// <summary>
        ///  Get方式请求市平台事件推送外网接口
        /// </summary>
        /// <param name="url">别人家的url</param>
        /// <param name="tokenk">请求头带token的key:默认Authorization</param>
        /// <param name="tokenv">请求头带token的value</param>
        /// <param name="contentType">默认text/html;charset=UTF-8</param>
        /// <returns>iteam1 状态码 200 成功 400 失败 item2 内容</returns>
        public static async Task<(HttpStatusCode, string)> Get_EventPush(string url, string tokenk = "Authorization", string tokenv = "", string contentType = "text/html;charset=UTF-8")
        {
            try
            {
                //编码格式，也就是postman里面 heard 部分的Content-Type
                using (HttpClient client = new HttpClient())
                {
                    //忽略ssl认证
                    ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
                    //编码格式，也就是postman里面 heard 部分的Content-Type
                    using (HttpContent requestContent = new StringContent(""/*, Encoding.UTF8*/))
                    {
                        requestContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
                        if (!string.IsNullOrEmpty(tokenk))
                        {
                            requestContent.Headers.Add($"{tokenv}", tokenv);
                        }
                        HttpResponseMessage httpResponse = await client.GetAsync(url);
                        httpResponse.EnsureSuccessStatusCode();
                        string result = await httpResponse.Content.ReadAsStringAsync();
                        //返回结果
                        return (httpResponse.StatusCode, result);
                    }
                }
            }
            catch (Exception ex)
            {
                return (HttpStatusCode.BadRequest, ex.ToString());
            }

        }

        /// <summary>
        /// Post方式请求外网接口
        /// </summary>
        /// <param name="url">别人家的url</param>
        /// <param name="jsonStr">文本化的Json字符串</param>
        /// <param name="tokenk">请求头带token的key:默认Authorization</param>
        /// <param name="tokenv">请求头带token的value</param>
        /// <param name="contentType">默认application/json</param>
        /// <returns>iteam1 状态码 200 成功 400 失败 item2 内容</returns>
        public static async Task<(HttpStatusCode, string)> Post_EventPush(string url, string jsonStr, string tokenk = "Authorization", string tokenv = "", string contentType = "application/json")
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    //忽略ssl认证
                    ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
                    //编码格式，也就是postman里面 heard 部分的Content-Type

                    //传入的参数：json文本字符串
                    using (HttpContent requestContent = new StringContent(jsonStr/*, Encoding.UTF8*/))
                    {
                        requestContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
                        if (!string.IsNullOrEmpty(tokenk))
                        {
                            requestContent.Headers.Add($"{tokenv}", tokenv);
                        }
                        HttpResponseMessage httpResponse = await client.PostAsync(url, requestContent);
                        httpResponse.EnsureSuccessStatusCode();
                        string result = await httpResponse.Content.ReadAsStringAsync();
                        return (httpResponse.StatusCode, result);
                    }

                }
            }
            catch (Exception ex)
            {
                return (HttpStatusCode.BadRequest, ex.ToString());
            }
        }
        #endregion
        public static string ApiGet(string url)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    HttpResponseMessage response = client.GetAsync(url).Result;
                    response.EnsureSuccessStatusCode();
                    string responseBody = response.Content.ReadAsStringAsync().Result;
                    // Above three lines can be replaced with new helper method below
                    // string responseBody = await client.GetStringAsync(uri);

                    return responseBody;
                }
            }
            catch (HttpRequestException e)
            {
                return e.Message;
            }
        }
        /// <summary>
        /// 发起POST同步请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postData"></param>
        /// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
        /// <param name="timeOut"></param>
        /// <param name="headers">填充消息头</param>        
        /// <returns></returns>
        public static string HttpPost(string url, string postData = null, Dictionary<string, string> headers = null, string contentType = "application/json", int timeOut = 30)
        {
            postData = postData ?? "";
            if (contentType == "application/x-www-form-urlencoded")
            {
                postData = JsonUrlEncode(postData);
            }
            using (HttpClient client = new HttpClient())
            {
                client.Timeout = TimeSpan.FromSeconds(timeOut);
                if (headers != null)
                {
                    foreach (var header in headers)
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                }
                using (HttpContent httpContent = new StringContent(postData, Encoding.UTF8))
                {
                    if (contentType != null)
                        httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
                    HttpResponseMessage response = client.PostAsync(url, httpContent).Result;
                    return response.Content.ReadAsStringAsync().Result;
                }
            }
        }
        /// <summary>
        /// json转urlencode
        /// </summary>
        /// <returns></returns>
        public static string JsonUrlEncode(string json)
        {
            Dictionary<string, object> dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
            StringBuilder builder = new StringBuilder();
            foreach (KeyValuePair<string, object> item in dic)
            {
                builder.Append(GetFormDataContent(item, ""));
            }
            return builder.ToString().TrimEnd('&');
        }

        /// <summary>
        /// 递归转formdata
        /// </summary>
        /// <param name="item"></param>
        /// <param name="preStr"></param>
        /// <returns></returns>
        private static string GetFormDataContent(KeyValuePair<string, object> item, string preStr)
        {
            StringBuilder builder = new StringBuilder();
            if (string.IsNullOrEmpty(item.Value?.ToString()))
            {
                builder.AppendFormat("{0}={1}", string.IsNullOrEmpty(preStr) ? item.Key : (preStr + "[" + item.Key + "]"), System.Web.HttpUtility.UrlEncode((item.Value == null ? "" : item.Value.ToString()).ToString()));
                builder.Append("&");
            }
            else
            {
                //如果是数组
                if (item.Value.GetType().Name.Equals("JArray"))
                {
                    var children = JsonConvert.DeserializeObject<List<object>>(item.Value.ToString());
                    for (int j = 0; j < children.Count; j++)
                    {
                        Dictionary<string, object> childrendic = JsonConvert.DeserializeObject<Dictionary<string, object>>(JsonConvert.SerializeObject(children[j]));
                        foreach (var row in childrendic)
                        {
                            builder.Append(GetFormDataContent(row, string.IsNullOrEmpty(preStr) ? (item.Key + "[" + j + "]") : (preStr + "[" + item.Key + "][" + j + "]")));
                        }
                    }

                }
                //如果是对象
                else if (item.Value.GetType().Name.Equals("JObject"))
                {
                    Dictionary<string, object> children = JsonConvert.DeserializeObject<Dictionary<string, object>>(item.Value.ToString());
                    foreach (var row in children)
                    {
                        builder.Append(GetFormDataContent(row, string.IsNullOrEmpty(preStr) ? item.Key : (preStr + "[" + item.Key + "]")));
                    }
                }
                //字符串、数字等
                else
                {
                    builder.AppendFormat("{0}={1}", string.IsNullOrEmpty(preStr) ? item.Key : (preStr + "[" + item.Key + "]"), System.Web.HttpUtility.UrlEncode((item.Value == null ? "" : item.Value.ToString()).ToString()));
                    builder.Append("&");
                }
            }

            return builder.ToString();
        }
    }
}